<?php
set_time_limit(0);

// generateNumbers();

//echo '<br>PHP inner function sort results:<br>';
//readInFileAndSort();
// echo '<br>Bubble sort results:<br>';
// readInFileAndBubbleSort();
// echo var_dump(bubbleSort(getFileContents('file_100.txt')));

//integerToBinary(0); echo '<br>';
//integerToBinary(1); echo '<br>';
//integerToBinary(16); echo '<br>';
//integerToBinary(13); echo '<br>';
//integerToBinary(11); echo '<br>';
//integerToBinary(2147483647); echo '<br>';
//integerToBinary(-2147483648); echo '<br>';
//sortAlreadySorted();

function generateNumbers() {
	$sizes = getSizes();
	foreach ($sizes as $size) {
		$file = fopen('file_' . $size . '.txt', 'w+');
		for ($i = 0; $i < $size; $i++) {
			$randomNumber = getRandomFloatingPointNumber(-100000000, 100000000);
			if (($i+1) == $size) {
				fwrite($file, $randomNumber);
			} else {
				fwrite($file, $randomNumber . PHP_EOL);
			}
			 
		}
		
		fclose($file);
	}
}

function repetitiveSort() {
	$sizes = getSizes();
	$results = fopen('results.txt', 'w+');
	
	fwrite($results, 'PHP native sort' . PHP_EOL);
	foreach ($sizes as $size) {
		$repetitions = 100;
		$fileName = 'file_' . $size .'.txt';
		$numbers = getFileContents($fileName);
		fwrite($results, $fileName . PHP_EOL);
		while ($repetitions > 0) {
			$start = microtime(true);
			sort($numbers);
			$end = microtime(true);
			fwrite($results, ($end - $start) . PHP_EOL);
			$repetitions--;
		}
	}
	
	fwrite($results, 'Bubble sort ' . PHP_EOL);
	foreach ($sizes as $size) {
		$repetitions = 100;
		$fileName = 'file_' . $size .'.txt';
		$numbers = getFileContents($fileName);
		fwrite($results, $fileName . PHP_EOL);
		while ($repetitions > 0) {
			$start = microtime(true);
			bubbleSort($numbers);
			$end = microtime(true);
			fwrite($results, ($end - $start) . PHP_EOL);
			$repetitions--;
		}
	}
	
	fclose($results);
}

// Sort already sorted
function sortAlreadySorted() {
	echo 'aa';
	$sizes = getSizes();
	$results = fopen('results2.txt', 'w+');
	fwrite($results, 'PHP native sort' . PHP_EOL);
	foreach ($sizes as $size) {
		$fileName = 'file_' . $size .'.txt';
		$numbers = getFileContents($fileName);
		sort($numbers);
		$start = microtime(true);
		sort($numbers);
		$end = microtime(true);
		fwrite($results, ($end - $start) . PHP_EOL);
	}
	
	fwrite($results, 'Bubble sort ' . PHP_EOL);
	foreach ($sizes as $size) {
		echo 'aa';
		$fileName = 'file_' . $size .'.txt';
		$numbers = getFileContents($fileName);
		$numbers = bubbleSort($numbers);
		
		$start = microtime(true);
		bubbleSort($numbers);
		$end = microtime(true);
		fwrite($results, ($end - $start) . PHP_EOL);
	}
	
	fclose($results);
}

function readInFileAndSort() {
	$sizes = getSizes();
	
	foreach ($sizes as $size) {
		$file = 'file_' . $size . '.txt';
		$numbers = explode(PHP_EOL, file_get_contents($file));
		$numbers = array_map('floatval', $numbers);

		$start = microtime(true);
		sort($numbers);
		$end = microtime(true);
		
		echo $file . ' - Sorting time: ' . ($end - $start) . ' (seconds)<br>';
	}
}

function getFileContents($fileName) {
	$numbers = explode(PHP_EOL, file_get_contents($fileName));
	$numbers = array_map('floatval', $numbers);
	
	return $numbers;
}

function readInFileAndBubbleSort() {
	$sizes = getSizes();
	
	foreach ($sizes as $size) {
		$file = 'file_' . $size . '.txt';
		$numbers = explode(PHP_EOL, file_get_contents($file));
		$numbers = array_map('floatval', $numbers);
		
		$start = microtime(true);
		bubbleSort($numbers);
		$end = microtime(true);
		
		echo $file . ' - Sorting time: ' . ($end - $start) . ' (seconds)<br>';
	}
}

function getSizes() {
	$sizes = array();
	$number = 10;
	for ($i = 1; $i <= 2; $i++) {
		$number *= 10;
		$sizes[] = $number;
	}
	
	return $sizes;
}

function getRandomFloatingPointNumber($min, $max) {
	
	return $min + mt_rand() / mt_getrandmax() * ($max - $min);
}

function integerToBinary($input) {
	$format = '%1$d = %2$s (control: %1$0' . (PHP_INT_SIZE * 8) . 'b)';
	$lsb = 1; // least significant bit, e.g. 00000001
	$binaryStringResult = '';
	
	// Dealing only with integers within range -(2^31) to 2^32; or what is specified by PHP core
	if ($input <= PHP_INT_MAX && $input >= ((-1)*PHP_INT_MAX - 1)) {
		$count = (PHP_INT_SIZE * 8);
		
		// Iterating over every bit 
		while ($count > 0) {
			
			// Checking whether the bits are set in both integers at the same position with AND operator
			if ($input & $lsb) {
				$binaryStringResult = '1' . $binaryStringResult;
			} else {
				$binaryStringResult = '0' . $binaryStringResult;
			}
			
			$lsb = $lsb << 1; // Shift left by one step
			$count--;
		}
		
		// Output of the result
		echo sprintf($format, $input, $binaryStringResult);
	}
}

/**
 * Bubble sort
 */
function bubbleSort($array) {

	$swapped = true;
	$size = count($array);
	while ($swapped) {
		$swapped = false;
		for ($i = 0; ($i+1) < $size; $i++) {
			if ($array[$i] > $array[$i+1]) {

				$temp = $array[$i];
				$array[$i] = $array[$i+1];
				$array[$i+1] = $temp;

				$swapped = true;
			}
		}
	}

	return $array;
}